package com.augurit.wf.jbpmex.assignee;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.augurit.common.system.convert.OmPositionConverter;
import com.augurit.common.system.service.org.IAcRoleService;
import com.augurit.common.system.service.org.IOmOrgService;
import com.augurit.common.system.service.org.IOmPositionService;
import com.augurit.common.system.service.org.IOmUserService;
import com.augurit.common.system.web.org.form.AcRoleForm;
import com.augurit.common.system.web.org.form.OmOrgForm;
import com.augurit.common.system.web.org.form.OmPositionForm;
import com.augurit.common.system.web.org.form.OmUserForm;
import com.augurit.common.util.lang.CollectionUtils;

/**
 * 
 */
@Service
@Transactional
public class AssigneeParser implements IAssigneeParser{
	
	public static final String ASSIGNEE_SEPARATOR = ",";
	public static final String ASSIGNEE_INNER_SEPARATOR = "\\.";
	public static final String ASSIGNEE_INNER_SEPARATOR2 = "#";
	
	public static final String ASSIGNEE_SYS_FLAG = "$";
	public static final String ASSIGNEE_ORG = "ORG";
	public static final String ASSIGNEE_ROLE = "ROLE";
	public static final String ASSIGNEE_POS = "POS";
	public static final String ASSIGNEE_GROUP = "GROUP";
	public static final String ASSIGNEE_USER = "USER";
	public static final String ASSIGNEE_ORG_FLAG = ASSIGNEE_SYS_FLAG + ASSIGNEE_ORG;
	public static final String ASSIGNEE_ROLE_FLAG = ASSIGNEE_SYS_FLAG + ASSIGNEE_ROLE;
	public static final String ASSIGNEE_POS_FLAG = ASSIGNEE_SYS_FLAG + ASSIGNEE_POS;
	public static final String ASSIGNEE_GROUP_FLAG = ASSIGNEE_SYS_FLAG + ASSIGNEE_GROUP;
	

	@Autowired
	private IAcRoleService acRoleService;
	
	@Autowired
	private IOmOrgService omOrgService;
	
	@Autowired
	private IOmUserService omUserService;
	
	@Autowired
	private IOmPositionService omPosService;
	
	/**
	 * 返回复合表达式无重复用户userkey数组
	 * @param assignee，格式为：$ROLE.manager,...
	 * @return
	 */
	public String[] parseToUserKeys(String assignee){
		if(assignee != null && assignee.trim().length() > 0){
			Set<String> userKeys = new LinkedHashSet();
	
			String[] singleAssignees = assignee.split(ASSIGNEE_SEPARATOR);
			for(String singleAssignee : singleAssignees){
				Set<String> set = parseUserKeysBySingleAssignee(singleAssignee);
				if(set != null && set.size() > 0)
					userKeys.addAll(set);
			}
			
			if(userKeys != null && userKeys.size() > 0)
				return CollectionUtils.toStringArray(userKeys);
		}
		return null;
	}
	
	/**
	 * 返回复合表达式无重复用户userkey数组
	 * @param assignee，格式为：USER#100,ROLE#1000,...
	 * @return
	 */
	public String[] convertToUserKeys(String assignee){
		if(assignee != null && assignee.trim().length() > 0){
			Set<String> userKeys = new LinkedHashSet();
	
			String[] singleAssignees = assignee.split(ASSIGNEE_SEPARATOR);
			for(String singleAssignee : singleAssignees){
				Set<String> set = convertToUserKeysBySingleAssignee(singleAssignee);
				userKeys.addAll(set);
			}
			
			if(userKeys != null && userKeys.size() > 0)
				return CollectionUtils.toStringArray(userKeys);
		}
		return null;
    }
	
	public String[] parseToOriginalNames(String assignee){
		if(assignee != null && assignee.trim().length() > 0){
			Set<String> originalNames = new LinkedHashSet();
	
			String[] singleAssignees = assignee.split(ASSIGNEE_SEPARATOR);
			for(String singleAssignee : singleAssignees){
				String originalName = parseOrginalNamesBySingleAssignee(singleAssignee);
				originalNames.add(originalName);
			}
			
			if(originalNames != null && originalNames.size() > 0)
				return CollectionUtils.toStringArray(originalNames);
		}
		return null;
	}
	
	/**
	 * 解析单个的assignee="wukq"或者assignee="$ROLE.dept_manager"
	 * @param assignee
	 * @return
	 */
	public Set<String> parseUserKeysBySingleAssignee(String assignee){
		if(assignee != null){
			
			//角色,如assignee="$ROLE.dept_manager"
			if(assignee.indexOf(ASSIGNEE_ROLE_FLAG) == 0)
				return parseUserKeysByRoleAssignee(assignee);
			
			//机构,如assignee="$ORG.O_zjb"
			else if(assignee.indexOf(ASSIGNEE_ORG_FLAG) == 0)
				return parseUserKeysByOrgAssignee(assignee);
			
			//岗位,如assignee="$POS.P_zjlzl"
			else if(assignee.indexOf(ASSIGNEE_POS_FLAG) == 0)
				return parseUserKeysByPosAssignee(assignee);
			
			//不需要解析的,如assignee="wukq"
			else{
				Set<String> result = new HashSet();
				result.add(assignee);
				return result;
			}
		}
		
		return null;
	}
	
	/**
	 * 解析单个的assignee
	 * @param assignee 例如：USER#100 或 ROLE#1000
	 * @return
	 */
	public Set<String> convertToUserKeysBySingleAssignee(String assignee){
		if(assignee != null){

			//角色,如assignee="ROLE#1000"
			if(assignee.indexOf(ASSIGNEE_ROLE) == 0)
				return convertToUserKeysByRoleAssignee(assignee);
			
			else if(assignee.indexOf(ASSIGNEE_USER) == 0)
				return convertToUserKeysByUserAssignee(assignee);
			
			else if(assignee.indexOf(ASSIGNEE_ORG) == 0)
				return convertToUserKeysByOrgAssignee(assignee);
			
			else if(assignee.indexOf(ASSIGNEE_POS) == 0)
				return convertToUserKeysByPosAssignee(assignee);
		}
		
		return null;
	}
	
	public String parseOrginalNamesBySingleAssignee(String assignee){
		if(assignee != null){
			
			//角色,如assignee="$ROLE.dept_manager"
			if(assignee.indexOf(ASSIGNEE_ROLE_FLAG) == 0)
				return parseRoleName(assignee);
			
			//机构,如assignee="$ORG.O_zjb"
			else if(assignee.indexOf(ASSIGNEE_ORG_FLAG) == 0)
				return parseOrgName(assignee);
			
			//岗位,如assignee="$POS.P_zjlzl"
			else if(assignee.indexOf(ASSIGNEE_POS_FLAG) == 0)
				return parsePosName(assignee);
			
			//不需要解析的,如assignee="wukq"
			else
				return getUserNameByUserKey(assignee);
		}
		
		return null;
	}
	
	/**
	 * assignee="$Role.dept_manager"
	 * @return
	 */
	public Set<String> parseUserKeysByRoleAssignee(String assignee){
		AcRoleForm acRoleForm = parseRole(assignee);
		return toUserKeysByRole(acRoleForm);
	}
	
	/**
	 * assignee="Role#1000"
	 * @return
	 */
	public Set<String> convertToUserKeysByRoleAssignee(String assignee){
		AcRoleForm acRoleForm = convertToRole(assignee);
		return toUserKeysByRole(acRoleForm);
	}
	
	private Set<String> toUserKeysByRole(AcRoleForm acRoleForm){
		if(acRoleForm != null){
			List<OmUserForm> users = acRoleService.getUsersByDirectRole(acRoleForm.getRoleId());
			return AssigneeUtils.getUserKeySet(users);
		}else
			return null;
	}
	
	public AcRoleForm parseRole(String assignee){
		if(assignee != null && assignee.indexOf(ASSIGNEE_ROLE_FLAG) == 0){
			String roleCode = assignee.split(ASSIGNEE_INNER_SEPARATOR)[1];
			return acRoleService.getRolesByCode(roleCode);
		}
		return null;
	}
	
	public AcRoleForm convertToRole(String assignee){
		if(assignee != null && assignee.indexOf(ASSIGNEE_ROLE) == 0){
			Long roleId = Long.valueOf(assignee.split(ASSIGNEE_INNER_SEPARATOR2)[1]);
			return acRoleService.get(roleId);
		}
		return null;
	}
	
	public String parseRoleName(String assignee){
		AcRoleForm acRoleForm = parseRole(assignee);
		
		if(acRoleForm != null){
			return acRoleForm.getRoleName();
		}else
			return "";
	}
	
	/**
	 * assignee="USER#100"
	 * @return
	 */
	public Set<String> convertToUserKeysByUserAssignee(String assignee){
		OmUserForm omUserForm = convertToUser(assignee);

		if(omUserForm != null){
			Set<String> result = new HashSet();
			result.add(omUserForm.getUserName());
			return result;
		}else
			return null;
	}

	public OmUserForm convertToUser(String assignee){
		if(assignee != null && assignee.indexOf(ASSIGNEE_USER) == 0){
			Long userId = Long.valueOf(assignee.split(ASSIGNEE_INNER_SEPARATOR2)[1]);
			return omUserService.get(userId);
		}
		return null;
	}
	
	/**
	 * 解析机构任务分配表达式的用户loginName列表,例子assignee="$ORG.O_zjb"
	 * @return
	 */
	public Set<String> parseUserKeysByOrgAssignee(String assignee){
		OmOrgForm omOrgForm = parseOrg(assignee);
		return toUserKeysByOrg(omOrgForm);
	}
	
	/**
	 * assignee格式如"ORG#10000"
	 * @return
	 */
	public Set<String> convertToUserKeysByOrgAssignee(String assignee){
		OmOrgForm omOrgForm = convertToOrg(assignee);
		return toUserKeysByOrg(omOrgForm);
	}
	
	private Set<String> toUserKeysByOrg(OmOrgForm omOrgForm){
		if(omOrgForm != null){
			List<Long> orgIds = omOrgService.getAllChildOrgIds(omOrgForm.getOrgId());
				
			if(orgIds == null)
				orgIds = new ArrayList();
				
			orgIds.add(omOrgForm.getOrgId());

			List<OmUserForm> users = omUserService.getUsersByOrgIds(orgIds);
			return AssigneeUtils.getUserKeySet(users);
		}
		
		return null;
	}
	
	public OmOrgForm parseOrg(String assignee){
		if(assignee != null && assignee.indexOf(ASSIGNEE_ORG_FLAG) == 0){
			String orgCode = assignee.split(ASSIGNEE_INNER_SEPARATOR)[1];
			return omOrgService.getOrgByCode(orgCode);
		}
		return null;
	}
	
	public OmOrgForm convertToOrg(String assignee){
		if(assignee != null && assignee.indexOf(ASSIGNEE_ORG) == 0){
			Long orgId = Long.valueOf(assignee.split(ASSIGNEE_INNER_SEPARATOR2)[1]);
			return omOrgService.get(orgId);
		}
		return null;
	}
	
	public String parseOrgName(String assignee){
		OmOrgForm omOrgForm = parseOrg(assignee);
		
		if(omOrgForm != null){
			return omOrgForm.getOrgName();
		}else
			return "";
	}
	
	
	/**
	 * 解析岗位任务分配表达式的用户loginName列表,例子assignee="$POS.P_zjlzl"
	 * @return
	 */
	public Set<String> parseUserKeysByPosAssignee(String assignee){
		OmPositionForm omPositionForm = parsePos(assignee);
		return toUserKeysByPos(omPositionForm);
	}
	
	/**
	 * assignee如"POS#10"
	 * @return
	 */
	public Set<String> convertToUserKeysByPosAssignee(String assignee){
		OmPositionForm omPositionForm = convertToPos(assignee);
		return toUserKeysByPos(omPositionForm);
	}
	
	private Set<String> toUserKeysByPos(OmPositionForm omPositionForm){
		if(omPositionForm != null){
			List<OmPositionForm> posList = omPosService.getAllChildPositions(omPositionForm.getPosId());
				
			if(posList == null)
				posList = new ArrayList();
				
			posList.add(omPositionForm);

			List<OmUserForm> users = omUserService.getUsersByPosIds(OmPositionConverter.convertFormsToPosIds(posList));
			return AssigneeUtils.getUserKeySet(users);
		}

		return null;
	}
	
	public OmPositionForm parsePos(String assignee){
		if(assignee != null && assignee.indexOf(ASSIGNEE_POS_FLAG) == 0){
			String posCode = assignee.split(ASSIGNEE_INNER_SEPARATOR)[1];
			return omPosService.getByPosCode(posCode);
		}
		return null;
	}
	
	public OmPositionForm convertToPos(String assignee){
		if(assignee != null && assignee.indexOf(ASSIGNEE_POS) == 0){
			Long posId = Long.valueOf(assignee.split(ASSIGNEE_INNER_SEPARATOR2)[1]);
			return omPosService.get(posId);
		}
		return null;
	}
	
	public String parsePosName(String assignee){
		OmPositionForm omPositionForm = parsePos(assignee);
		
		if(omPositionForm != null){
			return omPositionForm.getPosName();
		}else
			return "";
	}

	public String getUserNameByUserKey(String userKey){
		if(userKey != null && userKey.trim().length() > 0){
			return this.omUserService.getUserName(userKey);
		}
		return null;
	}

	/**
	 * 将assignee格式化,以便解析获取userId
	 */
    public String formatAssignee(String assignee){
    	if(assignee != null && assignee.trim().length()>0){
    		String formatAssignee = "";
    		
    		String assigees[] = assignee.split(",");
    		for(String str:assigees){
    			String strs[] = str.split("#");
    			String assigneeType = strs[0];//类型
    			Long assigneeId = Long.parseLong(strs[1]);//id
    			
    			if(assigneeType.equals("ROLE")){
    				String roleCode = this.acRoleService.get(assigneeId).getRoleCode();
    				formatAssignee = formatAssignee +"$ROLE."+roleCode+",";
    			}else if(assigneeType.equals("USER")){
    				String userCode = this.omUserService.get(assigneeId).getLoginName();
    				formatAssignee = formatAssignee +userCode+",";
    			}else if(assigneeType.equals("ORG")){
    				String orgCode = this.omOrgService.get(assigneeId).getOrgCode();
    				formatAssignee = formatAssignee +"$ORG."+orgCode+",";
    			}else if(assigneeType.equals("POS")){
    				String posCode = this.omPosService.get(assigneeId).getPosCode();
    				formatAssignee = formatAssignee +"$POS."+posCode+",";
    			}else if(assigneeType.equals("GROUP")){
    				/*String groupCode = this.omGroupService.get(assigneeId).getGroupCode();
    				formatAssignee = formatAssignee +"$GROUP"+groupCode+",";*/
    			}
    		}
    		//去掉最后的一个逗号
    		formatAssignee = formatAssignee.substring(0,formatAssignee.length()-1);
    		return formatAssignee;
    	}
    	return null;
    }
    
  //根据表达式获取他们的手机电话号码
	public List<String> getMobilePhoneNos(String assignee){
	    List<String> phoneNos = null;
	    if(assignee != null && assignee.trim().length()>0){
	        //解析表达式
	        String userKeys[] = this.parseToUserKeys(assignee);
	        if(userKeys != null && userKeys.length>0){
	            
	            //根据userKeys数组获取用户form对象列表
	            List<OmUserForm> userFormList  = this.omUserService.getUsersLoginNames(userKeys);
	            if(userFormList != null && userFormList.size()>0){
	                phoneNos = new ArrayList<String>();
	                
	                //获取用户手机号码
	                for(OmUserForm userForm : userFormList){
	                    if(userForm.getMobile() != null && userForm.getMobile().trim().length()>0)
	                        phoneNos.add(userForm.getMobile());
	                }
	            }
	        }
	    }
	    return phoneNos;
	}
}
